package tc.de.krawallmann.gravoblocks.game.model;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.state.StateBasedGame;

import tc.de.krawallmann.event.CommandKeyListener;

/**
 * The Class Tetris is the game model for the actual game.
 * @author KrawallMann
 * @version 1.0
 */
public class Tetris implements CommandKeyListener {

	private transient final TetrisGrid holdGrid;
	private transient final TetrisGrid mainGrid;
	private transient final TetrisGrid previewGrid;
	private transient ITetrisGameRule rule;

	/**
	 * Instantiates a new.
	 * 
	 * @param mainGridWidth
	 *            the main grid width
	 * @param mainGridHeight
	 *            the main grid height
	 * @param previewGridWidth
	 *            the preview grid width
	 * @param previewGridHeight
	 *            the preview grid height
	 * @param holdGridWidth
	 *            the hold grid width
	 * @param holdGridHeight
	 *            the hold grid height
	 */
	public Tetris(final int mainGridWidth, final int mainGridHeight, final int previewGridWidth,
			final int previewGridHeight, final int holdGridWidth, final int holdGridHeight,
			final AbstractTetrisGameRule rule) {
		mainGrid = new TetrisGrid(mainGridWidth, mainGridHeight);
		previewGrid = new TetrisGrid(previewGridWidth, previewGridHeight);
		holdGrid = new TetrisGrid(holdGridWidth, holdGridHeight);
		rule.setTetris(this);
		this.rule = rule;
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.input.CommandKeyListener#commandKeyPressed
	 * (tc.de.krawallmann.input.CommandKeyEvent)
	 */
	@Override
	public void commandKeyPressed(final String event) {
		if ("pause".equals(event)) {
			rule.setPauseRequest(true);
		} else if ("moveLeft".equals(event)) {
			rule.setMoveLeftRequest(true);
		} else if ("moveRight".equals(event)) {
			rule.setMoveRightRequest(true);
		} else if ("fall".equals(event)) {
			rule.setFallRequest(true);
		} else if ("hold".equals(event)) {
			rule.setHoldRequest(true);
		} else if ("rotateRight".equals(event)) {
			rule.setRotateRight(true);
		} else if ("rotateLeft".equals(event)) {
			rule.setRotateLeft(true);
		} else if ("alldown".equals(event)) {
			rule.setFallDownRequest(true);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.input.CommandKeyListener#commandKeyReleased
	 * (tc.de.krawallmann.input.CommandKeyEvent)
	 */
	@Override
	public void commandKeyReleased(final String event) {
		if ("moveLeft".equals(event)) {
			rule.setMoveLeftRequest(false);
			rule.setMoveLeftKeyDelay(0);
			rule.setLeftTimes(0);
		} else if ("moveRight".equals(event)) {
			rule.setMoveRightRequest(false);
			rule.setMoveRightKeyDelay(0);
			rule.setRightTimes(0);
		} else if ("fall".equals(event)) {
			rule.setFallRequest(false);
			rule.setFallKeyDelay(0);
			rule.setFallTimes(0);
		}
	}

	public TetrisGrid getHoldGrid() {
		return holdGrid;
	}

	public TetrisGrid getMainGrid() {
		return mainGrid;
	}

	public TetrisGrid getPreviewGrid() {
		return previewGrid;
	}

	public ITetrisGameRule getRule() {
		return rule;
	}

	public void reset() {
		getMainGrid().reset();
		getPreviewGrid().reset();
		getHoldGrid().reset();
		rule.reset();
	}

	public void setRule(final AbstractTetrisGameRule rule) {
		this.rule = rule;
	}

	public void update(final GameContainer container, final StateBasedGame game, final int delta) {
		rule.update(container, game, delta);
	}
}
